package top.bug.blog.schedule;

import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import top.bug.blog.annotation.ScheduledJob;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @author <a href="https://github.com/jiusi66">九思.</a>
 * @email 10837907@qq.com
 * @from <a href="https://www.52bug.top">递归茶馆-www.52bug.top</a>
 * @description 实现ApplicationRunner，在应用Ready后执行
 */
@Service
@Slf4j
public class AutoJobRegisterService implements ApplicationRunner {
    @Resource
    private Scheduler scheduler;

    /**
     * 用于获取Spring容器中的所有Bean
     */
    @Resource
    private ApplicationContext applicationContext;

    @Override
    public void run(ApplicationArguments args) {
        // 1. 扫描所有带有 @ScheduledJob 注解的Bean
        Map<String, Object> jobBeans = applicationContext.getBeansWithAnnotation(ScheduledJob.class);
        log.info("发现 {} 个需要自动注册的定时任务", jobBeans.size());

        for (Object jobBean : jobBeans.values()) {
            // 2. 获取注解信息
            Class<?> jobClass = jobBean.getClass();
            ScheduledJob annotation = jobClass.getAnnotation(ScheduledJob.class);

            if (!Job.class.isAssignableFrom(jobClass)) {
                log.error("类 {} 标注了 @ScheduledJob 但未实现 org.quartz.Job 接口，跳过注册", jobClass.getName());
                continue;
            }
            // 3. 注册任务
            registerJob((Class<? extends Job>) jobClass, annotation);
        }
    }

    /**
     * 将单个任务注册到Quartz调度器
     */
    private void registerJob(Class<? extends Job> jobClass, ScheduledJob annotation) {
        String jobName = annotation.jobName();
        String jobGroup = annotation.jobGroup();
        String cronExpression = annotation.cronExpression();
        boolean autoStart = annotation.autoStart();
        String description = annotation.description();

        try {
            JobKey jobKey = new JobKey(jobName, jobGroup);

            // 检查任务是否已存在（防止重复注册）
            if (scheduler.checkExists(jobKey)) {
                log.warn("任务已存在: {}.{}, 跳过自动注册", jobGroup, jobName);
                return;
            }

            // 构建JobDetail
            JobDetail jobDetail = JobBuilder.newJob(jobClass)
                    .withIdentity(jobKey)
                    .withDescription(description)
                    // 持久化
                    .storeDurably()
                    .build();

            // 构建CronTrigger
            TriggerKey triggerKey = new TriggerKey(jobName, jobGroup);
            CronTrigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
                    .forJob(jobDetail)
                    .build();

            // 将任务调度起来
            scheduler.scheduleJob(jobDetail, trigger);

            // 如果不自动启动，则暂停任务
            if (!autoStart) {
                scheduler.pauseJob(jobKey);
                log.info("定时任务注册成功并已暂停: {}.{} | Cron: [{}]", jobGroup, jobName, cronExpression);
            } else {
                log.info("定时任务注册成功并已启动: {}.{} | Cron: [{}]", jobGroup, jobName, cronExpression);
            }

        } catch (Exception e) {
            log.error("自动注册定时任务失败: {}.{}", jobGroup, jobName, e);
        }
    }
}